﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace CoachingOrganizer.WinPhone.UITools
{
    public static class UIHelper
    {
        private static readonly Dictionary<Guid, WeakReference<ViewModelBase>> _pagesViewModels = new Dictionary<Guid, WeakReference<ViewModelBase>>();

        private static Guid GetViewModelId<TViewModel>(TViewModel viewModel) where TViewModel : ViewModelBase
        {
            Guid id = Guid.NewGuid();
            _pagesViewModels.Add(id, new WeakReference<ViewModelBase>(viewModel));
            return id;
        }

        public static TViewModel GetViewModelById<TViewModel>(Guid id) where TViewModel : ViewModelBase
        {
            if (_pagesViewModels.ContainsKey(id))
            {
                ViewModelBase viewModelBase;
                return _pagesViewModels[id].TryGetTarget(out viewModelBase) ? (TViewModel)viewModelBase : null;
            }
            else
                return null;
        }

        public static TViewModel GetDataContext<TViewModel>(NavigationEventArgs navigationArgs) where TViewModel : ViewModelBase
        {
            if (!(navigationArgs.Parameter is Guid))
                return null;
            return GetViewModelById<TViewModel>((Guid)navigationArgs.Parameter);
        }

        public static bool GoToPage<TViewModel>(TViewModel targetViewModel, Type targetPageType) where TViewModel : ViewModelBase
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
                return false;
            Guid viewModelId = GetViewModelId(targetViewModel);
            rootFrame.Navigate(targetPageType, viewModelId);
            return true;
        }

        public static bool GoBack()
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
                return false;
            rootFrame.GoBack();
            return true;
        }

        public static bool GoForward()
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
                return false;
            rootFrame.GoForward();
            return true;
        }

        public static bool CanGoBack()
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
                return false;
            return rootFrame.CanGoBack;
        }

        public static bool CanGoForward()
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
                return false;
            return rootFrame.CanGoForward;
        }

        public static TElement GetUpperElement<TElement>(DependencyObject startElement) where TElement : DependencyObject
        {
            DependencyObject currentElement = startElement;
            do
                currentElement = VisualTreeHelper.GetParent(currentElement);
            while (currentElement != null && !(currentElement is TElement));
            return currentElement as TElement;
        }

        public static async Task ShowErrorMessageAsync(string contentMessageId, string titleId = null)
        {
            MessageDialog dialog = string.IsNullOrEmpty(titleId) ? new MessageDialog(Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView().GetString(contentMessageId))
                : new MessageDialog(Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView().GetString(contentMessageId), Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView().GetString(titleId));
            await dialog.ShowAsync();
        }

        public static async void ShowErrorMessage(string contentMessageId, string titleId = null)
        {
            await ShowErrorMessageAsync(contentMessageId, titleId);
        }
    }
}
